using Engine.Graphics;
using Engine.Graphics.VertexStructures;
using Engine.Shape;
using Scenario_Editor.Windows;
using SharpDX;
using System.Collections.Generic;
using System.Drawing;

namespace Scenario_Editor.Tools
{
    /// <summary>
    /// An interface to correspondent with the terrain.
    /// </summary>
    ///
    public interface ITerrain
    {
        #region Public Methods

        /// <summary>
        /// Returns the height from the give position.
        /// </summary>
        /// <param name="positionOnTerrain">the current position</param>
        /// <returns>the height at the position</returns>
        float GetHeightFromPosition(Vector3 positionOnTerrain);

        /// <summary>
        /// Register a mesh to the terrain.
        /// </summary>
        /// <param name="mesh"></param>
        void RegisterMesh(Meshobject mesh);

        /// <summary>
        /// Register a shape to the terrain.
        /// </summary>
        /// <param name="shape"></param>
        void RegisterShape(Shapes shape);

        /// <summary>
        /// Unregister a mesh from the terrain.
        /// </summary>
        /// <param name="mesh"></param>
        void UnRegisterMesh(Meshobject mesh);

        /// <summary>
        /// Unregister a mesh from the terrain.
        /// </summary>
        /// <param name="shape"></param>
        void UnRegisterShape(Shapes shape);

        /// <summary>
        /// Updates the mesh ids in the terrain.
        /// </summary>
        /// <param name="mesh"></param>
        void UpdateMeshIds(Meshobject mesh);

        /// <summary>
        /// Updates the shape ids.
        /// </summary>
        /// <param name="shape"></param>
        void UpdateShapeIDs(Shapes shape);

        /// <summary>
        /// Cells of Terrain.
        /// </summary>
        Cell[,] Cells { get; }

        /// <summary>
        /// number of cells per terrain sector
        /// </summary>
        int numberOfCellsPerSector { get; }

        /// <summary>
        /// number of sectors of terrain in X-direction.
        /// </summary>
        int nSectorsX { get; }

        /// <summary>
        /// number of sectors  of terrain in Y-direction.
        /// </summary>
        int nSectorsY { get; }

        /// <summary>
        /// Sectorsize of each sector. (standard is atm 1024.0f)
        /// </summary>
        int SECTORSIZE1 { get; set; }

        /// <summary>
        /// Gets the gamevertex from terrain.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        IGameVertex GetGameVertex(int x, int y);

        /// <summary>
        /// Sets the gamevertex at the given coordinate.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="vertex"></param>
        void SetGameVertex(int x, int y, IGameVertex vertex);

        /// <summary>
        /// Returns the sector coordinate  of the given cell coordinate.
        /// </summary>
        /// <param name="cellCoordinate"></param>
        /// <returns></returns>
        System.Drawing.Point GetSectorCoordinateFromCellCoordinate(System.Drawing.Point cellCoordinate);

        /// <summary>
        /// Adds the cell coordinate to the update list for the given sectorcoordinate.
        /// </summary>
        /// <param name="x">Sector coordinate ??</param>
        /// <param name="y">Sector coordinate ??</param>
        /// <param name="cellCoordinate"></param>
        void SetCoordinateForUpdates(int x, int y, System.Drawing.Point cellCoordinate);

        /// <summary>
        /// Vertices 
        /// </summary>
        MyOwnVertex.PositionNormalTextured[,] Vertices { get; }

        /// <summary>
        /// Recreate all sectors of terrain.
        /// </summary>
        /// <param name="loadingWindow"></param>
        void UpdateAllSectors(LoadingWindow loadingWindow);

        /// <summary>
        ///  Gets normal from intersected cell.
        /// </summary>
        /// <param name="cellCoordinateX"></param>
        /// <param name="cellCoordinateY"></param>
        /// <param name="ray"></param>
        /// <param name="positiveSide"></param>
        /// <param name="negativeSide"></param>
        /// <param name="angle"></param>
        /// <returns></returns>
        bool GetNormalFromCell(int cellCoordinateX, int cellCoordinateY, Ray ray, bool positiveSide, bool negativeSide, out float angle);

        /// <summary>
        /// Get cells coordinate from the given position.
        /// </summary>
        /// <param name="positionOnTerrain"></param>
        /// <returns></returns>
        System.Drawing.Point GetCellCoordinate(Vector3 positionOnTerrain);

        /// <summary>
        /// Gets the material id of the given position.
        /// </summary>
        /// <param name="cursorPosition"></param>
        /// <returns></returns>
        int GetMaterialID(Vector3 cursorPosition);

        /// <summary>
        /// Gets all cells which are in distance of the given radius and position.
        /// </summary>
        /// <param name="cursorPosition"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        List<System.Drawing.Point> GetCellsUnderCursor(Vector3 cursorPosition, decimal radius);

        /// <summary>
        /// set materialID to the cells of terrain.
        /// </summary>
        /// <param name="cursorPosition"></param>
        /// <param name="cellsWhichWhichShouldPainted"></param>
        /// <param name="value"></param>
        /// <param name="materialID"></param>
        /// <param name="viewDistance"></param>
        void PaintMaterialOnTerrain(Vector3 cursorPosition, List<System.Drawing.Point> cellsWhichWhichShouldPainted, decimal value, int materialID, float viewDistance);


        /// <summary>
        /// Adds cell coordinates to the proper sector.
        /// </summary>
        /// <param name="cellsWhichWhichShouldPainted"></param>
        void UpdateTheCells(List<System.Drawing.Point> cellsWhichWhichShouldPainted);

        /// <summary>
        /// Set the vertices which stored the gamevertex informations of the terrain.
        /// </summary>
        /// <param name="coordinate"></param>
        /// <param name="value"></param>
        /// <param name="addin"></param>
        void SetGameVertex(System.Drawing.Point coordinate, IGameVertex value, Scenario_Editor.AddinManager.IAddinScenarioEditor addin);

        Scenario_Editor.AddinManager.IAddinScenarioEditor AddinScenarioEditor { get; }

        #endregion Public Methods
    }
}